package lxs.swift.fn;

import lxs.swift.operation.Try;
import org.jetbrains.annotations.NotNull;

import java.util.function.Function;

public interface Func<T, R, E extends Throwable> extends Fn<Function<T, R>> {
    R apply(T t) throws E;

    @Override
    default Function<T, R> std() {
        return (t) -> Try.valueOf(() -> this.apply(t)).ret();
    }

    default <RR> Func<T, RR, E> map(Func<R, RR, E> map) {
        return (t) -> map.apply(this.apply(t));
    }

    /**
     * 将输入值返回
     */
    static <T, E extends Throwable> Func<T, T, E> self() {
        return t -> t;
    }

    /**
     * 返回null
     */
    static <T, R, E extends Throwable> Func<T, R, E> none() {
        return (t) -> null;
    }

    /**
     * 将传入的异常类型直接抛出
     */
    static <E extends Throwable, R> Func<E, R, E> explode() {
        return e -> {
            throw e;
        };
    }

    /**
     * 抛出指定信息和类型的异常
     */
    static <T, R, E extends Throwable> Func<T, R, E> panic(@NotNull E error) {
        return (t) -> {
            throw error;
        };
    }

    /**
     * 忽略输入，直接从supply获取值返回
     */
    static <T, R, E extends Throwable> Func<T, R, E> supply(Supply<R, E> supply) {
        return (t) -> supply.get();
    }
}
